<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>原型缺点</title>
	</head>
	<body>
		
		<p>1省略了构造函数传参初始化这一过程，带来的缺点就是初始化的值都是一致的。</p>
		2最大的缺点同时也是最大的有点，共享。
	<br />
		
		<p>解决办法 ：
		1可以使用构造函数+原型模型的组合</p>
		2动态原型模式(把构造函数和原型分装到一起)
		主要此时不可以在使用字面量的方式重写原型，因为会切断实例和原型之间的联系
		<br />
		3寄生构造函数 :
		<br />
		其实就是工厂模式+构造函数模式。这种模式比较通用但是不能确定对象关系，
		所有在可以使用前两种模式时不建议使用此模式。
	<br />
	4 稳妥构造函数
	在一些安全的环境中，比如禁止使用this和new ，这里的this是构造函数里不使用this
	这里的new 是在外部实例化构造函数时不使用new.这种创建方式叫做稳妥构造函数
	</body>
	
	<script>
		function Box(){}
		Box.prototype ={
			constructor :Box ,
			name:'Tom',
			age:200,
			family:['哥哥','姐姐','妹妹'],
			run :function(){
			return this.name +','+ this.age +','+ '运行中...';
				
			}
		};
		var box1 = new Box();
		alert(box1.family);//哥哥,姐姐,妹妹
		box1.family.push('弟弟');
		alert(box1.family);//哥哥,姐姐,妹妹,弟弟
		
		var box2 = new Box();
		alert(box2.family);//哥哥,姐姐,妹妹,弟弟:这里会共享了box1添加后的引用类型的原型
		
		
		
		//组合模式
		function Relative(name,age){//独立的
			this.name =name;
			this.age =age;
			this.family = ['哥哥','姐姐','妹妹'];
		}
		Relative.prototype ={ //需要共享的
			constructor :Relative,
			run :function(){
				return this.name +','+ this.age +','+ '运行中...';
			}
		}
		
		var someone = new Relative('lee',25);
		alert(someone.run());//lee,25,运行中...
		someone.family.push('叔叔');
		alert(someone.family);//哥哥,姐姐,妹妹,叔叔
		
		var sometwo = new Relative('jack',26);
		alert(sometwo.run());//jack,26,运行中...
		alert(sometwo.family);//哥哥,姐姐,妹妹
		
		
		//动态原型模式
		//将所有信息分装在一起
		function Family(name,age){ 
		    this.name =name;
			this.age =age;
			this.family = ['哥哥','姐姐','妹妹'];
			
	//原型初始化只要第一次初始化就可以了，没必要每次都初始化		
			if(typeof this.run !='function'){//判断this.run是否存在
				alert('原型初始化开始');
				Family.prototype.run = function(){
					return this.name +','+ this.age +','+ 'Family运行中...';
				};
				alert('原型初始化结束')
			}
		}
		
		var family1 = new Family('小明',19);
		alert(family1.run());//小明,19,Family运行中...
		family1.family.push('爷爷');
		alert(family1.family);//哥哥,姐姐,妹妹,爷爷
		
		var family2 = new Family('小红',20);
		alert(family2.run());//小红,20,Family运行中...
		alert(family2.family);//哥哥,姐姐,妹妹
		
		
		//3寄生构造函数
		function Example(name,age){
			var obj = new Object();
			obj.name = name;
			obj.age = age;
			obj.run = function(){
		return this.name +','+ this.age +','+ 'Example运行...';
			};
			return obj;
		}
		var exp = new Example('寄生构造',27);
		alert(exp.run())//寄生构造,27,Example运行...
		
		//4稳妥构造函数
		function ExampleTwo(name,age){
			var obj = new Object();
			obj.name = name;
			obj.age = age;
			obj.run = function(){
		return name +','+ age +','+ 'Example运行...';//没有this
			};
			return obj;
		}
			var exptwo =  Example('稳妥构造',27);//没有new 
			alert(exptwo.run());//稳妥构造,27,Example运行...
	</script>
</html>
